package com.jinxin.platform.cdsmsmgr.rpc;

import com.alibaba.fastjson.JSONObject;
import com.aliyuncs.exceptions.ClientException;
import com.jinxin.platform.base.api.annotation.*;
import com.jinxin.platform.base.api.constant.APCOSApiConstans;
import com.jinxin.platform.base.common.annotation.RegBusiness;
import com.jinxin.platform.base.common.pojo.JsonResult;
import com.jinxin.platform.cdsmsmgr.alisms.SmsFactory;
import com.jinxin.platform.cdsmsmgr.pojo.domains.*;
import com.jinxin.platform.cdsmsmgr.pojo.entity.*;
import com.jinxin.platform.cdsmsmgr.service.*;
import com.jinxin.platform.cdsmsmgr.utils.TxSmsUtil;
import com.jinxin.platform.cdsmsmgr.utils.Utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * All rights Reserved, Designed By www.beonelot.com
 *
 * @version: V1.0
 * @Copyright: www.beonelot.com Inc. All rights reserved.
 * @Description：
 * @Date: 2020-07-03
 * @Author: Lingnan
 **/
@RegBusiness(moduleKey = Constant.MODULE_KEY, className = Constant.MODULE_CLASS_NAME)
@Service
@Slf4j
public class SmsRpcService {
    @Autowired
    private ISmsAkInfoService smsAkInfoService;
    @Autowired
    private ISmsBusinessService businessService;
    @Autowired
    private ISmsSignService signService;
    @Autowired
    private ISmsTemplateService templateService;
    @Autowired
    private ISendRecordService sendRecordService;

    @APCOSApiOperation(value = "sendSms",description = "发送短信",infDict = "sendSms",
            reqDemo = "{\"businessModule\":\"用户注册\",\"smsType\":\"0\",\"receiveUser\":\"张三\"," +
                    "\"receivePhone\":\"13888888888\",\"params\":\"对应短信模板中缺失的参数,多个用英文逗号分割\"}",
            respDemo = "{\n" +
            "    \"BizId\": \"发送回执ID\",\n" +
            "    \"Code\": \"请求状态码,OK是成功\",\n" +
            "    \"Message\": \"状态码的描述\",\n" +
            "    \"RequestId\": \"请求ID\"\n" +
            "  }",
            infType = APCOSApiConstans.INF_TYPE_OTHER,infCategory = APCOSApiConstans.INF_CATEGORY_WEB,
            developers = {"那个男人"})
    @APCOSApiRequests({
            @APCOSApiRequest(name = "businessModule", value = "业务模块名称如用户注册", dict = "businessModule",matchType = APCOSApiConstans.MATCH_TYPE_EQ,
                    keyType = APCOSApiConstans.KEY_TYPE_STR,fieldType = APCOSApiConstans.FIELD_TYPE_GN,required = true,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",remark = "业务模块名称如用户注册"),
            @APCOSApiRequest(name = "smsType", value = "短信类型0验证码1短信2推广短信", dict = "smsType",matchType = APCOSApiConstans.MATCH_TYPE_EQ,
                    keyType = APCOSApiConstans.KEY_TYPE_STR,fieldType = APCOSApiConstans.FIELD_TYPE_GN,required = true,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",remark = "短信类型0验证码1短信"),
            @APCOSApiRequest(name = "receiveUser", value = "接收短信的人员", dict = "receiveUser",matchType = APCOSApiConstans.MATCH_TYPE_EQ,
                    keyType = APCOSApiConstans.KEY_TYPE_STR,fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",remark = "接收短信的人员"),
            @APCOSApiRequest(name = "receivePhone", value = "接收短信的手机号码", dict = "receivePhone",matchType = APCOSApiConstans.MATCH_TYPE_EQ,
                    keyType = APCOSApiConstans.KEY_TYPE_STR,fieldType = APCOSApiConstans.FIELD_TYPE_GN,required = true,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",remark = "接收短信的手机号码"),
            @APCOSApiRequest(name = "params", value = "对应短信模板中缺失的参数", dict = "params",matchType = APCOSApiConstans.MATCH_TYPE_EQ,
                    keyType = APCOSApiConstans.KEY_TYPE_STR,fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "2000",remark = "多个用英文逗号分割"),
    })
    @APCOSApiResponses({
            @APCOSApiResponse(name = "BizId", value = "发送回执ID", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",dict = "发送回执ID",remark = "发送回执ID",keyType = APCOSApiConstans.KEY_TYPE_STR),
            @APCOSApiResponse(name = "Code", value = "请求状态码", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",dict = "请求状态码",remark = "OK是成功",keyType = APCOSApiConstans.KEY_TYPE_STR),
            @APCOSApiResponse(name = "Message", value = "状态码的描述", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "32",dict = "状态码的描述",remark = "状态码的描述",keyType = APCOSApiConstans.KEY_TYPE_STR),
            @APCOSApiResponse(name = "RequestId", value = "请求ID", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "255",dict = "请求ID",remark = "请求ID",keyType = APCOSApiConstans.KEY_TYPE_STR),

    })
    public JsonResult sendSms(Map param1){
        if(param1 == null){
            return JsonResult.error("参数不能为空");
        }
        String businessModule = param1.containsKey("businessModule") ? (String) param1.get("businessModule") : "";
        String smsType = param1.containsKey("smsType") ? (String) param1.get("smsType") : "";
        String receiveUser = param1.containsKey("receiveUser") ? (String) param1.get("receiveUser") : "";
        String receivePhone = param1.containsKey("receivePhone") ? (String) param1.get("receivePhone") : "";
        String paramStr = param1.containsKey("params") ? (String) param1.get("params") : "";
        String sepSymbol = Constant.ENGLISH_COMMA;//英文逗号
        String[] paramArr = paramStr.split(sepSymbol);
        List<String> paramList = !StringUtils.isEmpty(paramStr) ? Arrays.asList(paramArr) : new ArrayList<>();
        if(StringUtils.isEmpty(businessModule) || StringUtils.isEmpty(smsType) || StringUtils.isEmpty(receivePhone)){
            return JsonResult.error("业务模块名称businessModule和业务短信类型smsType均不能为空");
        }
        ResultEntity akInfoResult = smsAkInfoService.getAkInfoByUser();
        if(akInfoResult == null || StringUtils.isEmpty(akInfoResult.getResultContent())){
            return JsonResult.error("获取ak信息失败");
        }
        SmsAkInfo akInfo = (SmsAkInfo)akInfoResult.getResultContent();
        HashMap param = new HashMap();
        param.put("name", businessModule);
        param.put("type", Integer.parseInt(smsType));
//        String userAccount = akInfo.getUserAccount();
        param.put("applyUser", Constant.ACCOUNT_ADMIN);// 只有admin的配置才有效
        SmsBusinessInfo smsBusinessInfo = businessService.getOne(param);
        if(smsBusinessInfo == null){
            return JsonResult.error("请先添加短信业务，并配置短信签名和模板");
        }
        if(Constant.SMS_BUSINESS_UNSETTED.equals(smsBusinessInfo.getIsSetSign())){
            return JsonResult.error("请配置短信签名");
        }
        if(Constant.SMS_BUSINESS_UNSETTED.equals(smsBusinessInfo.getIsSetTemplate())){
            return JsonResult.error("请配置短信模板");
        }
        SmsSignInfo signInfo = signService.getById(smsBusinessInfo.getSignId());
        if(signInfo == null){
            return JsonResult.error("短信签名不存在或已删除");
        }
        String templateId = smsBusinessInfo.getTemplateId();
        SmsTemplateInfo templateInfo = templateService.getById(templateId);
        if(templateInfo == null){
            return JsonResult.error("短信模板不存在或已删除");
        }
        String akId = akInfo.getAkId();
        String akSecret = akInfo.getAkSecret();
        String signName = signInfo.getSignName();
        String templateCode = templateInfo.getCode();
        String accountType = akInfo.getThirdAccountType();
        String templateContent = templateInfo.getContent();
        boolean isTxAccount = Constant.TX_ACCOUNT.equals(accountType);//是否是腾讯账号
        // 腾讯:查看模板中是否含有{}，若有就需要传入短信模板变量对应的实际值，String数组。
        // 阿里:查看模板中是否含有${}，若有就需要传入短信模板变量对应的实际值，JSON格式。
        String regex = isTxAccount ? "\\{([1-9][0-9]*)}" : "\\$\\{(.*?)}";
        Pattern p = Pattern.compile(regex);
        Matcher matcher = p.matcher(templateContent);
        int count=0;   //匹配的数量
        int index =0;
        JSONObject jsonObject = new JSONObject();
        int size = paramList.size();
        String sendContent = templateContent; // 发送内容
        while (matcher.find()){
            count++;
            if(count > size){
                return JsonResult.error("模板实际值与变量的个数不匹配");
            }
            String group = matcher.group();
            String val = paramList.get(index);
            sendContent = sendContent.replace(group,val);
            if(!isTxAccount){
                jsonObject.put(group.substring(2,group.length()-1), val);
                index++;
            }
        }
        if(count < size){
            return JsonResult.error("模板实际值与变量的个数不匹配");
        }
        JsonResult jsonResult;
        if(isTxAccount){
            TxSmsSendParam smsSendParam = new TxSmsSendParam();
            smsSendParam.setSecretId(akId);
            smsSendParam.setSecretKey(akSecret);
            smsSendParam.setPhoneNumberSet(new String[]{receivePhone});
            if(count > 0){
                smsSendParam.setTemplateParamSet(paramArr);
            }
            smsSendParam.setSmsSdkAppId(akInfo.getAppid());
            smsSendParam.setTemplateId(templateCode);
            smsSendParam.setSignName(signName);
            jsonResult = TxSmsUtil.sendSms(smsSendParam);
        }else {
            Map<String, Object> map = new HashMap<>();
            map.put(SmsConstant.ACCESS_KEY_ID, akId);
            map.put(SmsConstant.ACCESS_SECERT,akSecret);
            map.put(SmsConstant.PHONE_NUMBERS, receivePhone);
            map.put(SmsConstant.SIGN_NAME, signName);
            map.put(SmsConstant.TEMPLATE_CODE, templateCode);
            if(count > 0){ // 有变量
                map.put(SmsConstant.TEMPLATE_PARAM, jsonObject.toString());
            }
            SmsSendResult sendResult;
            try {
                Map<String, Object> resultMap = SmsFactory.aliSendSms(map);
                sendResult = (SmsSendResult)resultMap.get(SmsConstant.RESULT);
            } catch (ClientException e) {
                e.printStackTrace();
                return JsonResult.error("发送短信失败: " + e.getMessage());
            }
            if(sendResult == null){
                return JsonResult.error("发送短信失败");
            }
            if(Constant.STRING_OK.equals(sendResult.getCode())){
                jsonResult = JsonResult.ok("发送短信成功",sendResult);
            }else {
                log.error(sendResult.toString());
                jsonResult = JsonResult.error("发送短信失败: " + sendResult.getMessage());
            }
        }
        // 发送成功写入记录表
        if(jsonResult.getSuccess()){
            SmsSendRecord sendRecord = new SmsSendRecord();
            sendRecord.setUserName(receiveUser);
            sendRecord.setPhoneNumber(receivePhone);
            sendRecord.setTemplateId(templateId);
            sendRecord.setSendContent(sendContent);
            Integer accType = isTxAccount ? Constant.ACCOUNT_TYPE_TX : Constant.ACCOUNT_TYPE_ALI;
            sendRecord.setAccountType(accType);
            sendRecordService.saveOrUpdate(sendRecord);
            return JsonResult.ok("发送成功",jsonResult.getData());
        }
        return jsonResult;
    }

    @APCOSApiOperation(value = "queryTemplateByBusiness",description = "通过业务模块查询短信模板",infDict = "通过业务模块查询短信模板",
            reqDemo = "{\"businessModule\":\"用户注册\",\"smsType\":\"0\"}",
            respDemo = "{\"id\":\"模板id\",\"code\":\"模板code\",\"name\":\"模板名称\",\"content\":\"模板内容\",\"status\":\"审核状态0审核中1审核通过2审核不通过\"}",
            infType = APCOSApiConstans.INF_TYPE_OTHER,infCategory = APCOSApiConstans.INF_CATEGORY_WEB,
            developers = {"那个男人"})
    @APCOSApiRequests({
            @APCOSApiRequest(name = "businessModule", value = "业务模块名称如用户注册", dict = "businessModule",matchType = APCOSApiConstans.MATCH_TYPE_EQ,
                    keyType = APCOSApiConstans.KEY_TYPE_STR,fieldType = APCOSApiConstans.FIELD_TYPE_GN,required = true,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",remark = "业务模块名称如用户注册"),
            @APCOSApiRequest(name = "smsType", value = "短信类型0验证码1短信", dict = "smsType",matchType = APCOSApiConstans.MATCH_TYPE_EQ,
                    keyType = APCOSApiConstans.KEY_TYPE_STR,fieldType = APCOSApiConstans.FIELD_TYPE_GN,required = true,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",remark = "短信类型0验证码1短信"),
    })
    @APCOSApiResponses({
            @APCOSApiResponse(name = "id", value = "模板id", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",dict = "模板id",remark = "模板id",keyType = APCOSApiConstans.KEY_TYPE_STR),
            @APCOSApiResponse(name = "code", value = "模板code", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",dict = "模板code",remark = "模板code",keyType = APCOSApiConstans.KEY_TYPE_STR),
            @APCOSApiResponse(name = "name", value = "模板名称", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",dict = "模板名称",remark = "模板名称",keyType = APCOSApiConstans.KEY_TYPE_STR),
            @APCOSApiResponse(name = "content", value = "模板内容", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "2000",dict = "模板内容",remark = "模板内容",keyType = APCOSApiConstans.KEY_TYPE_STR),
            @APCOSApiResponse(name = "status", value = "审核状态", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_NUM,lenth = "1,0",dict = "审核状态",remark = "审核状态0审核中1审核通过2审核不通过",keyType = APCOSApiConstans.KEY_TYPE_STR),

    })
    public JsonResult queryTemplateByBusiness(Map param1){
        if(param1 == null){
            return new JsonResult(JsonResult.CODE_404,"参数不能为空",null);
        }
        String businessModule = param1.containsKey("businessModule") ? (String) param1.get("businessModule") : "";
        String smsType = param1.containsKey("smsType") ? (String) param1.get("smsType") : "";
        if(StringUtils.isEmpty(businessModule) || StringUtils.isEmpty(smsType)){
            return JsonResult.error("业务模块名称businessModule和业务短信类型smsType均不能为空");
        }
        HashMap param = new HashMap();
        param.put("name", businessModule);
        param.put("type", Integer.parseInt(smsType));
        param.put("applyUser", Constant.ACCOUNT_ADMIN);// 只有admin的配置才有效
        SmsBusinessInfo smsBusinessInfo = businessService.getOne(param);
        if(smsBusinessInfo == null){
            return JsonResult.error("请先添加短信业务，并配置短信签名和模板");
        }
        String templateId = smsBusinessInfo.getTemplateId();
        if(StringUtils.isEmpty(templateId) || Constant.SMS_BUSINESS_UNSETTED.equals(smsBusinessInfo.getIsSetTemplate())){
            return new JsonResult(JsonResult.CODE_404,"请配置短信模板",null);
        }
        SmsTemplateInfo templateInfo = templateService.getById(templateId);
        return JsonResult.ok("success",templateInfo);
    }

    // 批量发送短信
    @APCOSApiOperation(value = "sendBatchSms",description = "批量发送(同样内容)短信",infDict = "sendBatchSms",
            reqDemo = "{\"businessModule\":\"短信通知\",\"smsType\":\"0\",\"receiveUsers\":\"二狗子,王麻子\"," +
                    "\"receivePhones\":\"13888888888,13666666666\",\"params\":\"对应短信模板中缺失的参数,多个用英文逗号分割\"}",
            respDemo = "{\n" +
                    "    \"BizId\": \"发送回执ID\",\n" +
                    "    \"Code\": \"请求状态码,OK是成功\",\n" +
                    "    \"Message\": \"状态码的描述\",\n" +
                    "    \"RequestId\": \"请求ID\"\n" +
                    "  }",
            infType = APCOSApiConstans.INF_TYPE_OTHER,infCategory = APCOSApiConstans.INF_CATEGORY_WEB,
            developers = {"那个男人"})
    @APCOSApiRequests({
            @APCOSApiRequest(name = "businessModule", value = "业务模块名称如短信通知", dict = "businessModule",matchType = APCOSApiConstans.MATCH_TYPE_EQ,
                    keyType = APCOSApiConstans.KEY_TYPE_STR,fieldType = APCOSApiConstans.FIELD_TYPE_GN,required = true,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",remark = "业务模块名称如短信通知"),
            @APCOSApiRequest(name = "smsType", value = "短信类型0验证码1短信2推广短信", dict = "smsType",matchType = APCOSApiConstans.MATCH_TYPE_EQ,
                    keyType = APCOSApiConstans.KEY_TYPE_STR,fieldType = APCOSApiConstans.FIELD_TYPE_GN,required = true,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",remark = "短信类型0验证码1短信"),
            @APCOSApiRequest(name = "receiveUsers", value = "接收短信的人员", dict = "receiveUsers",matchType = APCOSApiConstans.MATCH_TYPE_EQ,
                    keyType = APCOSApiConstans.KEY_TYPE_STR,fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",remark = "接收短信的人员,多个用逗号分隔"),
            @APCOSApiRequest(name = "receivePhones", value = "接收短信的手机号码", dict = "receivePhones",matchType = APCOSApiConstans.MATCH_TYPE_EQ,
                    keyType = APCOSApiConstans.KEY_TYPE_STR,fieldType = APCOSApiConstans.FIELD_TYPE_GN,required = true,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",remark = "接收短信的手机号码,多个用逗号分隔"),
            @APCOSApiRequest(name = "params", value = "对应短信模板中缺失的参数", dict = "params",matchType = APCOSApiConstans.MATCH_TYPE_EQ,
                    keyType = APCOSApiConstans.KEY_TYPE_STR,fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "2000",remark = "多个用英文逗号分割"),
    })
    @APCOSApiResponses({
            @APCOSApiResponse(name = "BizId", value = "发送回执ID", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",dict = "发送回执ID",remark = "发送回执ID",keyType = APCOSApiConstans.KEY_TYPE_STR),
            @APCOSApiResponse(name = "Code", value = "请求状态码", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "50",dict = "请求状态码",remark = "OK是成功",keyType = APCOSApiConstans.KEY_TYPE_STR),
            @APCOSApiResponse(name = "Message", value = "状态码的描述", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "32",dict = "状态码的描述",remark = "状态码的描述",keyType = APCOSApiConstans.KEY_TYPE_STR),
            @APCOSApiResponse(name = "RequestId", value = "请求ID", fieldType = APCOSApiConstans.FIELD_TYPE_GN,
                    dataType = APCOSApiConstans.DATA_TYPE_STR,lenth = "255",dict = "请求ID",remark = "请求ID",keyType = APCOSApiConstans.KEY_TYPE_STR),

    })
    public JsonResult sendBatchSms(Map param1){
        if(param1 == null){
            return JsonResult.error("参数不能为空");
        }
        String businessModule = param1.containsKey("businessModule") ? (String) param1.get("businessModule") : "";
        String smsType = param1.containsKey("smsType") ? (String) param1.get("smsType") : "";
        String receiveUsers = param1.containsKey("receiveUsers") ? (String) param1.get("receiveUsers") : "";
        String receivePhones = param1.containsKey("receivePhones") ? (String) param1.get("receivePhones") : "";
        String paramStr = param1.containsKey("params") ? (String) param1.get("params") : "";
        String sepSymbol = Constant.ENGLISH_COMMA;//英文逗号
        String[] phoneArr = receivePhones.split(sepSymbol);
        String[] userNameArr = receiveUsers.split(sepSymbol);
        int nameLen = userNameArr.length;
        int phoneCount = phoneArr.length;
        if(nameLen > 0 && nameLen != phoneCount){
            return JsonResult.error("接收短信的用户数量必须与接收短信手机数量保持一致");
        }
        // "aaa,bbb,456"
        String[] paramArr = paramStr.split(sepSymbol);
        List<String> paramList =Arrays.asList(paramArr);
        if(StringUtils.isEmpty(businessModule) || StringUtils.isEmpty(smsType) || StringUtils.isEmpty(receivePhones)){
            return JsonResult.error("业务模块名称,业务短信类型及手机号码均不能为空");
        }
        ResultEntity akInfoResult = smsAkInfoService.getAkInfoByUser();
        if(akInfoResult == null || StringUtils.isEmpty(akInfoResult.getResultContent())){
            return JsonResult.error("获取ak信息失败");
        }
        SmsAkInfo akInfo = (SmsAkInfo)akInfoResult.getResultContent();
        HashMap param = new HashMap();
        param.put("name", businessModule);
        param.put("type", Integer.parseInt(smsType));
        String userAccount = akInfo.getUserAccount();
        param.put("applyUser", Constant.ACCOUNT_ADMIN);// 只有admin的配置才有效
        SmsBusinessInfo smsBusinessInfo = businessService.getOne(param);
        if(smsBusinessInfo == null){
            return JsonResult.error("请先添加短信业务，并配置短信签名和模板");
        }
        if(Constant.SMS_BUSINESS_UNSETTED.equals(smsBusinessInfo.getIsSetSign())){
            return JsonResult.error("请配置短信签名");
        }
        if(Constant.SMS_BUSINESS_UNSETTED.equals(smsBusinessInfo.getIsSetTemplate())){
            return JsonResult.error("请配置短信模板");
        }
        SmsSignInfo signInfo = signService.getById(smsBusinessInfo.getSignId());
        if(signInfo == null){
            return JsonResult.error("短信签名不存在或已删除");
        }
        String templateId = smsBusinessInfo.getTemplateId();
        SmsTemplateInfo templateInfo = templateService.getById(templateId);
        if(templateInfo == null){
            return JsonResult.error("短信模板不存在或已删除");
        }
        String akId = akInfo.getAkId();
        String akSecret = akInfo.getAkSecret();
        String signName = signInfo.getSignName();
        String templateCode = templateInfo.getCode();
        String accountType = akInfo.getThirdAccountType();
        String templateContent = templateInfo.getContent();
        boolean isTxAccount = Constant.TX_ACCOUNT.equals(accountType);//是否是腾讯账号
        // 腾讯:查看模板中是否含有{}，若有就需要传入短信模板变量对应的实际值，String数组。
        // 阿里:查看模板中是否含有${}，若有就需要传入短信模板变量对应的实际值，JSON格式。
        String regex = isTxAccount ? "\\{([1-9][0-9]*)}" : "\\$\\{(.*?)}";
        Pattern p = Pattern.compile(regex);
        Matcher matcher = p.matcher(templateContent);
        int count = 0;   //匹配的数量
        int index = 0;
        int size = paramList.size();

        String sendContent = templateContent;//发送内容
        JSONObject jsonObject = new JSONObject();
        while (matcher.find()){
            count++;
            if(count > size){
                return JsonResult.error("模板实际值与变量的个数不匹配");
            }
            String group = matcher.group();
            String val = paramList.get(index);
            sendContent = sendContent.replace(group,val);
            if(!isTxAccount){ // 阿里
                jsonObject.put(group.substring(2,group.length()-1),val);
                index++;
            }
        }
        if(count < size){
            return JsonResult.error("模板实际值与变量的个数不匹配");
        }
        JsonResult jsonResult;
        if(isTxAccount){
            TxSmsSendParam smsSendParam = new TxSmsSendParam();
            smsSendParam.setSecretId(akId);
            smsSendParam.setSecretKey(akSecret);
            smsSendParam.setPhoneNumberSet(phoneArr);
            if(count > 0){
                smsSendParam.setTemplateParamSet(paramArr);
            }
            smsSendParam.setSmsSdkAppId(akInfo.getAppid());
            smsSendParam.setTemplateId(templateCode);
            smsSendParam.setSignName(signName);
            jsonResult = TxSmsUtil.sendSms(smsSendParam);
        }else {
            Map<String, Object> map = new HashMap<>();
            JSONObject[] templateParamArr = new JSONObject[nameLen];
            StringBuilder phoneJsonSb = new StringBuilder(Constant.LEFT_BRACKET);
            StringBuilder signNameJsonSb = new StringBuilder(Constant.LEFT_BRACKET);
            String comma = Constant.COMMA;
            // 模板变量值的个数必须与手机号码、签名的个数相同、内容一一对应，
            // 表示向指定手机号码中发对应签名的短信，且短信模板中的变量参数替换为对应的值
            for (int i = 0; i < nameLen; i++) {
                templateParamArr[i] = jsonObject;
                String append = i == nameLen - Constant.NUMBER_ONE ? "" : comma;
                signNameJsonSb.append(signName).append(append);
                phoneJsonSb.append(phoneArr[i]).append(append);
            }
            signNameJsonSb.append(Constant.CLOSE_BRACKET);
            phoneJsonSb.append(Constant.CLOSE_BRACKET);
            map.put(SmsConstant.ACCESS_KEY_ID, akId);
            map.put(SmsConstant.ACCESS_SECERT,akSecret);
            map.put(SmsConstant.PHONE_NUMBER_JSON, phoneJsonSb.toString());
            //必须是已添加、并通过审核的短信签名；且短信签名的个数必须与手机号码的个数相同、内容一一对应。
            map.put(SmsConstant.SIGN_NAME_JSON, signNameJsonSb.toString());
            map.put(SmsConstant.TEMPLATE_CODE, templateCode);
            if(count > 0){ // 有变量
                //[阿里]:短信模板变量对应的实际值。
                //且模板变量值的个数必须与手机号码、签名的个数相同、内容一一对应，表示向指定手机号码中发对应签名的短信，
                // 且短信模板中的变量参数替换为对应的值。
                map.put(SmsConstant.TemplateParamJson, Arrays.toString(templateParamArr));
            }
            SmsSendResult sendResult;
            try {
                Map<String, Object> resultMap = SmsFactory.aliSendBatchSms(map);
                sendResult = (SmsSendResult)resultMap.get(SmsConstant.RESULT);
            } catch (ClientException e) {
                e.printStackTrace();
                return JsonResult.error("发送短信异常: " + e.getMessage());
            }
            if(sendResult == null){
                return JsonResult.error("发送短信失败");
            }
            if(Constant.STRING_OK.equals(sendResult.getCode())){
                jsonResult = JsonResult.ok("发送短信成功",sendResult);
            }else {
                log.error(sendResult.toString());
                jsonResult = JsonResult.error("发送短信失败: " + sendResult.getMessage());
            }
        }
        // 发送成功写入记录表
        if(jsonResult.getSuccess()){
            List<SmsSendRecord> sendRecords = new ArrayList<>();
            Integer accType = isTxAccount ? Constant.ACCOUNT_TYPE_TX : Constant.ACCOUNT_TYPE_ALI;
            for (int i = 0; i < phoneCount; i++) {
                SmsSendRecord sendRecord = new SmsSendRecord();
                sendRecord.setId(Utils.getUuid());
                sendRecord.setUserName(userNameArr[i]);
                sendRecord.setPhoneNumber(phoneArr[i]);
                sendRecord.setSendTime(LocalDateTime.now());
                sendRecord.setTemplateId(templateId);
                sendRecord.setSendContent(sendContent);
                sendRecord.setOperateUser(Constant.ACCOUNT_ADMIN);
                sendRecord.setAccountType(accType);
                sendRecords.add(sendRecord);
            }
            sendRecordService.batchInsert(sendRecords);
            return JsonResult.ok("发送成功",jsonResult.getData());
        }
        return jsonResult;
    }
}
